/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.planning.tactical;

import java.awt.BorderLayout;
import java.text.SimpleDateFormat;
import java.util.logging.Logger;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import nl.cloudfarming.client.model.ProductionUnit;
import nl.cloudfarming.client.model.DataProvider;
import nl.cloudfarming.client.model.Task;
import nl.cloudfarming.client.planning.PlanEventKey;
import nl.cloudfarming.eventbus.GuiEvent;
import nl.cloudfarming.eventbus.GuiEventBus;
import nl.cloudfarming.eventbus.GuiEventKey;
import nl.cloudfarming.eventbus.GuiEventListener;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.UndoRedo;
import org.openide.explorer.ExplorerManager;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;

/**
 * Topcomponent will represent operations and tasks. It wil register itself as lookuplistener on ProductionUnitNode
 * @author Merijn Zengers
 */
@ConvertAsProperties(dtd = "-//nl.cloudfarming.client.planning.tactical//ActionViewerTopcomponent//EN",
autostore = false)
public class ActionViewerTopcomponent extends TopComponent implements LookupListener, ExplorerManager.Provider {

    private static ActionViewerTopcomponent instance;
    private static final String PREFERRED_ID = "ActionViewerTopcomponent";
    private static final String ACTIONNAME_COLUMNHEADER = NbBundle.getMessage(ActionViewerTopcomponent.class, "actionviewertopcomponent.table.column.header.name");
    private static final String STARTDATE_COLUMNHEADER = NbBundle.getMessage(ActionViewerTopcomponent.class, "actionviewertopcomponent.table.column.header.plandate");
    private static final String[] COLUMNAMES = new String[]{ACTIONNAME_COLUMNHEADER, STARTDATE_COLUMNHEADER};
    private final TacticalPlanningService service;
    private DefaultTableModel actionTableModel;
    private JTable actionTable;
    
    private static final int ROWCOUNT = 10;
    private JScrollPane pane;
    private Lookup.Result result = null;
    private DataProvider dataProvider;

    public ActionViewerTopcomponent() {
        initComponents();
        setName(NbBundle.getMessage(ActionViewerTopcomponent.class, "CTL_ActionViewerTopcomponent"));
        setToolTipText(NbBundle.getMessage(ActionViewerTopcomponent.class, "HINT_ActionViewerTopcomponent"));

        service = Lookup.getDefault().lookup(TacticalPlanningService.class);
        assert service != null;
        associateLookup(service.getLookup());

        GuiEventBus.addListener(new GuiEventListener() {

            @Override
            public void onEvent(GuiEvent event) {
                updateTable();
            }

            @Override
            public boolean listensTo(GuiEventKey guiEventKey) {
                return PlanEventKey.NEW_OPERATION.equals(guiEventKey);
            }

            @Override
            public String getModuleName() {
                return TacticalPlanningModule.MODULE_NAME;
            }
        });

    }

    private void initComponents() {
        setLayout(new BorderLayout());
        pane = new JScrollPane();
        actionTableModel = new DefaultTableModel(COLUMNAMES, ROWCOUNT);
        actionTable = new JTable(actionTableModel);
        pane.setViewportView(actionTable);
        add(pane);
    }

    /**
     * Gets default instance. Do not use directly: reserved for *.settings files only,
     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
     * To obtain the singleton instance, use {@link #findInstance}.
     */
    public static synchronized ActionViewerTopcomponent getDefault() {
        if (instance == null) {
            instance = new ActionViewerTopcomponent();
        }
        return instance;
    }

    /**
     * Obtain the TacticalPlanningExplorerTopComponent instance. Never call {@link #getDefault} directly!
     */
    public static synchronized ActionViewerTopcomponent findInstance() {
        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
        if (win == null) {
            Logger.getLogger(ActionViewerTopcomponent.class.getName()).warning(
                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
            return getDefault();
        }
        if (win instanceof ActionViewerTopcomponent) {
            return (ActionViewerTopcomponent) win;
        }
        Logger.getLogger(ActionViewerTopcomponent.class.getName()).warning(
                "There seem to be multiple components with the '" + PREFERRED_ID
                + "' ID. That is a potential source of errors and unexpected behavior.");
        return getDefault();
    }

    @Override
    protected String preferredID() {
        return PREFERRED_ID;
    }

    @Override
    public UndoRedo getUndoRedo() {
        return service.getUndoredoManager();
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
    }

    Object readProperties(java.util.Properties p) {
        if (instance == null) {
            instance = this;
        }
        instance.readPropertiesImpl(p);
        return instance;
    }

    private void readPropertiesImpl(java.util.Properties p) {
    }

    @Override
    public void componentOpened() {
        result = Utilities.actionsGlobalContext().lookupResult(ProductionUnitNode.class);
        result.addLookupListener(this);
    }

    @Override
    public void componentClosed() {
        result = Utilities.actionsGlobalContext().lookupResult(ProductionUnitNode.class);
        result.removeLookupListener(this);

    }

    public void updateTable() {
        ProductionUnit productionUnit = Utilities.actionsGlobalContext().lookup(ProductionUnit.class);
        if (productionUnit != null) {
            while (actionTableModel.getRowCount() > 0) {
                actionTableModel.removeRow(0);
            }
            int i = 0;
            for (Task task : service.findTaskByProductionUnitId(productionUnit.getId())) {
                String formattedPlanDate = null;
                if (task.getPlanDate() != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                    formattedPlanDate = sdf.format(task.getPlanDate());
                }
                actionTableModel.insertRow(i, new Object[]{task.getOperation().getName(), formattedPlanDate});
                i++;
            }
        }
    }

    @Override
    public void resultChanged(LookupEvent le) {
        updateTable();
    }

    public void setDataProvider(DataProvider dataProvider) {
        this.dataProvider = dataProvider;
    }

    @Override
    public int getPersistenceType() {
        return PERSISTENCE_ALWAYS;
    }
    
    

    @Override
    public ExplorerManager getExplorerManager() {
        return dataProvider == null ? new ExplorerManager() : dataProvider.getExplorerManager();
    }

    @Override
    public Lookup getLookup() {
        return dataProvider == null ? super.getLookup() : dataProvider.getLookup();
    }
}
